package com.ja.sevice.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ja.check.action.FootBallCheckOrder;
import com.ja.check.data.FootballData;
import com.ja.dao.FootBallMatchMapper;
import com.ja.domain.FootBallMatch;
import com.ja.domain.FootballMatchResult;
import com.ja.sevice.FootBallMatchService;
import com.ja.util.JsonResult;

@Service
public class FootBallMatchServiceImpl implements FootBallMatchService{
	
	@Autowired
	private FootBallMatchMapper fMatchMapper;

	@Override
	public List<FootBallMatch> findTypeMatch(String play, String type,String time) {
		return fMatchMapper.findTypeMatch(play, type,time);
	}
	
	@Override
	public List<FootBallMatch> findMatchInfo(String cname,String play, String type, String time) {
		List<FootBallMatch> list = fMatchMapper.findMatch(cname,play,type, time);
		List<FootBallMatch> ls = new ArrayList<FootBallMatch>();
		for(int i=0;i<list.size();i++) {
			FootBallMatch fm = fMatchMapper.findMatchInfo(list.get(i).getId());
			ls.add(fm);
		}
		return ls;
	}

	@Override
	public FootBallMatch findOneMatchInfo(Integer id) {
		return fMatchMapper.findMatchInfo(id);
	}
	
	@Override
	public JsonResult getFootballData() {
		FootballData footballData = new FootballData();
		List<FootBallMatch> datas = null;
		long start = System.currentTimeMillis();
		int count = 0;
		datas = footballData.crawlPanKou(FootballData.URL_FUTURE_DS,FootballData.TYPES_FUTURE,FootballData.PLAY_TYPE_DS);
		System.out.println("早盘单式："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_FUTURE_BD,FootballData.TYPES_FUTURE,FootballData.PLAY_TYPE_BD));
		System.out.println("早盘波胆："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_FUTURE_RQS,FootballData.TYPES_FUTURE,FootballData.PLAY_TYPE_RQS));
		System.out.println("早盘入球数："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_FUTURE_BQC,FootballData.TYPES_FUTURE,FootballData.PLAY_TYPE_BQC));
		System.out.println("早盘半全场："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_FUTURE_ZHGG,FootballData.TYPES_FUTURE,FootballData.PLAY_TYPE_ZHGG));
		System.out.println("早盘综合过关："+(datas.size()-count));
		count = datas.size();
		
		datas.addAll(footballData.crawlPanKou(FootballData.URL_TODAY_DS,FootballData.TYPES_TODAY,FootballData.PLAY_TYPE_DS));
		System.out.println("今日单式："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_TODAY_BD,FootballData.TYPES_TODAY,FootballData.PLAY_TYPE_BD));
		System.out.println("今日波胆："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_TODAY_RQS,FootballData.TYPES_TODAY,FootballData.PLAY_TYPE_RQS));
		System.out.println("今日入球数："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_TODAY_BQC,FootballData.TYPES_TODAY,FootballData.PLAY_TYPE_BQC));
		System.out.println("今日半全场："+(datas.size()-count));
		count = datas.size();
		datas.addAll(footballData.crawlPanKou(FootballData.URL_TODAY_ZHGG,FootballData.TYPES_TODAY,FootballData.PLAY_TYPE_ZHGG));
		System.out.println("今日综合过关："+(datas.size()-count));
		count = datas.size();
		
		datas.addAll(footballData.crawlPanKou(FootballData.URL_GQ,FootballData.TYPES_GQ,FootballData.PLAY_TYPE_GQ));
		System.out.println("滚球："+(datas.size()-count));
		System.out.println("------------总的数据量为："+datas.size()+"--------------");
		saveOrUpdate(datas);
		long end = System.currentTimeMillis();
		System.out.println("【用时】："+(end-start)/1000.0+"秒");
		System.out.println("---------------------------------------"+LocalDateTime.now().toString()+"---------------------------------------------");
		return new JsonResult("足球盘口数据爬取完成。", null);
	}
	
	/**
	 * 更新爬取的数据
	 * @param datas
	 */
	private void saveOrUpdate(List<FootBallMatch> datas) {	
		//初始化：比对前的数据准备
		List<FootBallMatch> newDatasOfNotDSAndNotGQ = new ArrayList<>();
		List<FootBallMatch> newDatasOfDSAndGQ = new ArrayList<>();
		
		initListByType(datas,newDatasOfNotDSAndNotGQ,newDatasOfDSAndGQ);

		List<FootBallMatch> datasInserted = new ArrayList<>();
		List<Integer> idsOfDeleted = new ArrayList<>();
		List<Integer> idsOfSameMatches = new ArrayList<>();
		
		/*
		 * 根据每种玩法将新旧数据进行比对-依次拿着新数据去旧数据集合中比较：
		 *	1、插入：如果没有比对成功，则将当前数据实体放入待插入数据集合；
		 *	2：软删除-更新为过期：等全部数据比对完成，将待更新数据集合中的id放入待处理集合。
		 */
		//非滚球非单式玩法的数据比对处理
		for (int i=0; i < newDatasOfNotDSAndNotGQ.size(); i++) {
			FootBallMatch newMatch = newDatasOfNotDSAndNotGQ.get(i);
			//如果当前实体有数据才进行处理
			if(!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDy_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getRq_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDx_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDs_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getFh_dy_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getFh_rq_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getFh_dx_h()) ||
					
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getRq01()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getRq23()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getRq46()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getRq7()) ||
					
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf10_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf20_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf21_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf30_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf31_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf32_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf40_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf41_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf42_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf43_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf10_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf20_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf21_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf30_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf31_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf32_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf40_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf41_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf42_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf43_c()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf00()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf11()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf22()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf33()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getBf44()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getOther()) ||
					
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getHh()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getHc()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getHd()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getCh()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getCc()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getCd()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDh()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDc()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDd())
					) {
				
				try {
					List<FootBallMatch> oldMatches = fMatchMapper.findByMatchInfoOfNotDSAndNotGQ(
							newMatch.getType(), newMatch.getTypes(), newMatch.getLeague(),
							newMatch.getStart_time(), newMatch.getTeam_h(), newMatch.getTeam_c());
					if(oldMatches != null && oldMatches.size() > 0) {
						FootBallMatch oldMatch = oldMatches.get(0);
						if(!newMatch.equals(oldMatch)) {						
							datasInserted.add(newMatch);
						}else {
							idsOfSameMatches.add(oldMatch.getId());
						}
						if(oldMatches.size() > 1) {
							//System.out.println("-----非单式非滚球玩法从数据库查到重复数据："+(oldMatches.size() - 1)+"条！-----");
							for (int j=1; j< oldMatches.size(); j++) {
								idsOfDeleted.add(oldMatches.get(j).getId());
							}
						}
					}else {
						datasInserted.add(newMatch);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		}
		int notListRepeatedSize = idsOfSameMatches.size();
		System.out.println("-------------非单式非滚球爬到的数据量为："+newDatasOfNotDSAndNotGQ.size()+"，重复的数据量为："+notListRepeatedSize);
		
		//单式和滚球玩法的数据比对处理
		for (int i=0; i < newDatasOfDSAndGQ.size(); i++) {
			FootBallMatch newMatch = newDatasOfDSAndGQ.get(i);
			//如果当前实体有数据则进行处理
			if(!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDy_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getRq_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDx_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getDs_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getFh_dy_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getFh_rq_h()) ||
					!FootBallMatch.DEFAULT_INIT_VALUE.equals(newMatch.getFh_dx_h())) {
				
				try {
					List<FootBallMatch> oldMatches = fMatchMapper.findByMatchInfoOfDSAndGQ(newMatch);
					if(oldMatches != null && oldMatches.size() > 0) {
						FootBallMatch oldMatch = oldMatches.get(0);
						if(!newMatch.equals(oldMatch)) {						
							datasInserted.add(newMatch);
						}else {
							idsOfSameMatches.add(oldMatch.getId());
						}
						if(oldMatches.size() > 1) {
							System.out.println("-----单式和滚球玩法从数据库查到重复数据："+(oldMatches.size() - 1)+"条！-----");
							for (int j=1; j< oldMatches.size(); j++) {
								idsOfDeleted.add(oldMatches.get(j).getId());
							}
						}
					}else {
						datasInserted.add(newMatch);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		System.out.println("-------------单式和滚球爬到的数据量为："+newDatasOfDSAndGQ.size()+"，重复的数据量为："+
				(idsOfSameMatches.size()-notListRepeatedSize));
		List<Integer> oldIds = null;
		try {
			oldIds = fMatchMapper.findIdsOfLatest();
			oldIds.removeAll(idsOfSameMatches);
			oldIds.addAll(idsOfDeleted);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//将处理后的数据持久化到数据库
		syncDB(datasInserted,oldIds);
		
	}

	/**
	 * 将处理后的数据持久化到数据库
	 * @param datasInserted
	 * @param datasUpdated
	 * @param idsOfUpdated
	 */
	private void syncDB(List<FootBallMatch> datasInserted, List<Integer> oldIds) {
		try {
			if(!datasInserted.isEmpty()) {			
				System.out.println("传递到数据库的集合长度为："+datasInserted.size());
				int count = fMatchMapper.insertByBatch(datasInserted);
				System.out.println("插入的数据量为："+count);
			}
			if(!oldIds.isEmpty()) {
				System.out.println("过期的数据量为："+oldIds.size());
				fMatchMapper.updateOutDatedByBatch(oldIds);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 根据玩法将比赛集合中的数据分流到相应的玩法集合
	 * @param datas
	 * @param listOfNotDSAndNotGQ
	 * @param listOfDSAndGQ
	 */
	private void initListByType(List<FootBallMatch> datas, List<FootBallMatch> listOfNotDSAndNotGQ,
			List<FootBallMatch> listOfDSAndGQ) {
		if(datas != null) {
			for (FootBallMatch d : datas) {
				if(FootballData.PLAY_TYPE_DS.equals(d.getType()) || FootballData.PLAY_TYPE_GQ.equals(d.getType())) {
					listOfDSAndGQ.add(d);					
				}else {
					listOfNotDSAndNotGQ.add(d);					
				}
			}
		}
	}

	@Override
	public JsonResult getFootballResult() {
		FootballData footballData = new FootballData();
		List<FootballMatchResult> results = footballData.crawlSaiGuo(FootballData.URL_PREDAY_SG);
		System.out.println("前一天赛果的数据量："+results.size());
		try {			
			if(!results.isEmpty()) {				
				fMatchMapper.updateResultByBatch(results);
				new FootBallCheckOrder().checks();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new JsonResult("赛果数据爬取成功。", null);	
	}

	@Override
	public String findStartTime(String league, String team_h, String team_c, String date) {
		List<String> startTimes = fMatchMapper.findStartTime(league, team_h, team_c, date.substring(5, 10)+"%");
		if(!startTimes.isEmpty()) {
			return startTimes.get(0);
		}else {
			return FootBallMatch.DEFAULT_INIT_VALUE;
		}
	}

	@Override
	public List<FootBallMatch> findMatchResult(String date) {
		return fMatchMapper.findMatchResult(date);
	}

	
}
